# -*- coding: utf-8 -*-
"""
流水线命令行接口
提供分步执行的CLI工具
"""

import argparse
import json
import logging
from pathlib import Path
from typing import List, Optional, Dict, Any

from .pipeline import Pipeline
from .step_base import StepResult
from .steps import (
    ParseMarkdownStep,
    GenerateScenesStep,
    SynthesizeTTSStep,
    GenerateAnimationsStep,
    RenderVideoStep,
)

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
)
logger = logging.getLogger(__name__)


class PipelineCLI:
    """流水线CLI工具"""

    def __init__(self):
        self.parser = self._create_parser()

    def _create_parser(self) -> argparse.ArgumentParser:
        """创建参数解析器"""
        parser = argparse.ArgumentParser(
            description="视频生成流水线工具",
            formatter_class=argparse.RawDescriptionHelpFormatter,
            epilog="""
示例用法:
  # 运行完整流水线
  %(prog)s run /path/to/markdown.md --output /path/to/output

  # 从断点恢复
  %(prog)s run /path/to/markdown.md --resume

  # 仅执行特定步骤
  %(prog)s step parse_markdown /path/to/markdown.md --output /path/to/output

  # 查看流水线状态
  %(prog)s status --checkpoint /path/to/checkpoint

  # 清理断点
  %(prog)s clear --checkpoint /path/to/checkpoint
            """,
        )

        parser.add_argument(
            "command",
            choices=["run", "step", "status", "clear"],
            help="要执行的命令",
        )

        # 通用参数
        parser.add_argument(
            "--output",
            type=Path,
            default=Path("output"),
            help="输出目录",
        )
        parser.add_argument(
            "--checkpoint",
            type=Path,
            default=Path("checkpoints"),
            help="断点目录",
        )
        parser.add_argument(
            "--force",
            action="store_true",
            help="强制执行（跳过缓存）",
        )
        parser.add_argument(
            "--theme",
            type=str,
            default="dark",
            choices=["dark", "light", "academic", "presentation"],
            help="视觉主题",
        )
        parser.add_argument(
            "--quality",
            type=str,
            default="standard",
            choices=["preview", "standard", "high", "ultra"],
            help="输出质量",
        )
        parser.add_argument(
            "--verbose",
            action="store_true",
            help="详细输出",
        )

        # run命令特定参数
        parser.add_argument(
            "input",
            nargs="?",
            help="输入文件（Markdown或JSON）",
        )
        parser.add_argument(
            "--resume",
            action="store_true",
            help="从断点恢复",
        )
        parser.add_argument(
            "--skip-render",
            action="store_true",
            help="跳过视频渲染步骤",
        )

        # step命令特定参数
        parser.add_argument(
            "step_name",
            nargs="?",
            help="要执行的步骤名",
        )

        return parser

    def run(self, args: Optional[List[str]] = None) -> int:
        """
        运行CLI

        Args:
            args: 命令行参数

        Returns:
            退出码
        """
        parsed_args = self.parser.parse_args(args)

        # 设置日志级别
        if parsed_args.verbose:
            logging.getLogger().setLevel(logging.DEBUG)

        try:
            if parsed_args.command == "run":
                return self._cmd_run(parsed_args)
            elif parsed_args.command == "step":
                return self._cmd_step(parsed_args)
            elif parsed_args.command == "status":
                return self._cmd_status(parsed_args)
            elif parsed_args.command == "clear":
                return self._cmd_clear(parsed_args)
            else:
                self.parser.error(f"Unknown command: {parsed_args.command}")

        except KeyboardInterrupt:
            print("\nOperation cancelled by user")
            return 1
        except Exception as e:
            logger.exception(f"Unexpected error: {e}")
            return 1

    def _cmd_run(self, args) -> int:
        """执行run命令"""
        if not args.input:
            print("Error: input file required for 'run' command")
            return 1

        input_path = Path(args.input)
        if not input_path.exists():
            print(f"Error: input file not found: {input_path}")
            return 1

        print(f"Starting pipeline: {input_path.name}")
        print(f"Output directory: {args.output}")
        print(f"Theme: {args.theme}")
        print(f"Quality: {args.quality}")
        print("-" * 50)

        # 创建流水线
        pipeline = self._create_pipeline(input_path, args.output, args)

        # 运行流水线
        result = pipeline.run(from_checkpoint=args.resume)

        print("-" * 50)
        if result.success:
            print(f"✓ Pipeline completed successfully!")
            print(f"  {result.message}")
            if "total_steps" in result.data:
                total = result.data["total_steps"]
                completed = result.data.get("completed_steps", 0)
                skipped = result.data.get("skipped_steps", 0)
                print(f"  Steps: {completed} completed, {skipped} skipped")
            return 0
        else:
            print(f"✗ Pipeline failed!")
            print(f"  {result.message}")
            return 1

    def _cmd_step(self, args) -> int:
        """执行step命令"""
        if not args.step_name:
            print("Error: step name required for 'step' command")
            return 1

        print(f"Executing step: {args.step_name}")
        print(f"Output directory: {args.output}")
        print("-" * 50)

        # 创建流水线
        pipeline = self._create_pipeline(Path(), args.output, args)

        # 执行指定步骤
        result = pipeline.run_step(args.step_name, force=args.force)

        print("-" * 50)
        if result.success:
            print(f"✓ Step completed successfully!")
            print(f"  {result.message}")
            return 0
        else:
            print(f"✗ Step failed!")
            print(f"  {result.message}")
            return 1

    def _cmd_status(self, args) -> int:
        """执行status命令"""
        from .checkpoint_manager import CheckpointManager

        checkpoint_manager = CheckpointManager(args.checkpoint)

        if not checkpoint_manager.has_checkpoint():
            print("No checkpoint found")
            return 1

        # 加载状态
        state = checkpoint_manager.load_pipeline_state()
        if not state:
            print("Failed to load checkpoint")
            return 1

        # 显示状态
        print(f"Pipeline: {state['pipeline_name']}")
        print(f"Timestamp: {state['timestamp']}")
        print(f"Current step: {state['current_step'] or 'N/A'}")
        print(f"Total steps: {len(state['steps'])}")
        print("-" * 50)

        # 显示每个步骤的状态
        for step_name, step_state in state["steps"].items():
            status = step_state["status"]
            duration = step_state.get("duration", 0)
            error = step_state.get("error_message", "")

            print(f"  {step_name}: {status}")
            if duration > 0:
                print(f"    Duration: {duration:.2f}s")
            if error:
                print(f"    Error: {error}")

        return 0

    def _cmd_clear(self, args) -> int:
        """执行clear命令"""
        from .checkpoint_manager import CheckpointManager

        checkpoint_manager = CheckpointManager(args.checkpoint)

        if not checkpoint_manager.has_checkpoint():
            print("No checkpoint to clear")
            return 0

        # 确认清理
        response = input(f"Clear checkpoint at {args.checkpoint}? [y/N]: ")
        if response.lower() != "y":
            print("Operation cancelled")
            return 0

        # 清理断点
        checkpoint_manager.clear_checkpoint()
        print("Checkpoint cleared successfully")
        return 0

    def _create_pipeline(
        self,
        input_path: Path,
        output_dir: Path,
        args,
    ) -> Pipeline:
        """
        创建流水线

        Args:
            input_path: 输入路径
            output_dir: 输出目录
            args: 命令行参数

        Returns:
            流水线实例
        """
        # 创建步骤
        steps = []

        # 步骤1: 解析Markdown
        if not args.skip_render:
            parse_step = ParseMarkdownStep(
                markdown_file=input_path,
                output_dir=output_dir / "01_parse",
                force_run=args.force,
            )
            steps.append(parse_step)

            # 步骤2: 生成场景
            generate_step = GenerateScenesStep(
                output_dir=output_dir / "02_scenes",
                theme=args.theme,
                force_run=args.force,
            )
            steps.append(generate_step)

            # 步骤3: TTS合成
            tts_step = SynthesizeTTSStep(
                output_dir=output_dir / "03_tts",
                voice_config={"voice": "zh-CN-XiaoxiaoNeural"},
                output_format="mp3",
                force_run=args.force,
            )
            steps.append(tts_step)

            # 步骤4: 生成动画
            anim_step = GenerateAnimationsStep(
                output_dir=output_dir / "04_animations",
                quality=args.quality,
                force_run=args.force,
            )
            steps.append(anim_step)

            # 步骤5: 渲染视频
            render_step = RenderVideoStep(
                output_dir=output_dir / "05_render",
                output_settings={
                    "format": "mp4",
                    "quality": args.quality,
                    "resolution": "1920x1080",
                },
                force_run=args.force,
            )
            steps.append(render_step)

        # 创建流水线
        pipeline = Pipeline(
            name=f"video_generation_{input_path.stem}",
            steps=steps,
            checkpoint_dir=args.checkpoint,
            auto_save=True,
        )

        # 设置进度回调
        def progress_callback(percent: int, message: str):
            print(f"\r[{percent:3d}%] {message}", end="", flush=True)

        pipeline.set_progress_callback(progress_callback)

        return pipeline


def main():
    """主函数"""
    cli = PipelineCLI()
    exit_code = cli.run()
    exit(exit_code)


if __name__ == "__main__":
    main()
